package com.smartwebx.fr.util;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.smartwebx.fr.bean.SimpleUseArgConf;

/**
 * 占位符参数替换
 * 
 * @author zhangxi
 * 
 */
public class ParamSubsti {

	public static String pageParamSub(String target, String pageParam) {
		ObjectMapper mapper = new ObjectMapper();
		Map<String, String> params = Maps.newHashMap();
		try {
			params = mapper.readValue(pageParam,
					new TypeReference<Map<String, String>>() {
					});
		} catch (IOException e) {
			e.printStackTrace();
		}

		return replaceByMap(target, params);
	}

	public static String replaceByMap(String target,
			Map<String, String> nameValMap) {
		Collection<String> searchKey = nameValMap.keySet();
		String[] searchKeyArr = new String[searchKey.size()];
		for (int i = 0; i < searchKey.size(); i++) {
			searchKeyArr[i] = "#{" + Iterables.get(searchKey, i) + "}";
		}
		String[] searchValArr = Iterables.toArray(nameValMap.values(),
				String.class);

		target = StringUtils.replaceEachRepeatedly(target, searchKeyArr,
				searchValArr);
		return target;
	}

	public static Entry<String, List<String>> replaceSignByMap(String str,
			Map<String, String> nameValMap) {
		String[] findSigns = { "\"", "'" };
		List<Integer[]> startEnds = Lists.newArrayList();
		int start = -1;
		int end = -1;
		for (String sign : findSigns) {
			while (true) {
				start = str.indexOf(sign, start + 1);
				if (start == -1)
					break;
				end = start;
				end = str.indexOf(sign, end + 1);
				startEnds.add(new Integer[] { start, end });
				start = end;
			}
		}
		
		List<Integer[]> replaceStartEnds = Lists.newArrayList();
		List<String> sqlParams = Lists.newArrayList();
		for (Integer[] startEnd : startEnds) {
			String subStr = str.substring(startEnd[0]+1, startEnd[1]);
			boolean isFind = false;
			for (String key : nameValMap.keySet()) {
				if (subStr.indexOf(key) >= 0) {
					subStr = StringUtils.replace(subStr, "#{" + key + "}",
							nameValMap.get(key));
					isFind = true;
				}
			}
			if (isFind) {
				sqlParams.add(subStr);
				replaceStartEnds.add(startEnd);
			}
		}

		if (!replaceStartEnds.isEmpty()) {
			StringBuffer strBuffer = new StringBuffer(str);
			for (int i = replaceStartEnds.size() - 1; i >= 0; i--) {
				strBuffer = strBuffer.replace(replaceStartEnds.get(i)[0], replaceStartEnds.get(i)[1]+1, "?");
			}
			str = strBuffer.toString();
		}

		return Maps.immutableEntry(str, sqlParams);
	}

	public static Entry<String, List<String>> pageParamReplace(String code,
			List<SimpleUseArgConf> simpleUseArgs) {
		Map<String, String> nameValMap = getNameVal(simpleUseArgs);
		return replaceSignByMap(code, nameValMap);
	}

	public static String pageParamReplaceByStr(String code,
			List<SimpleUseArgConf> simpleUseArgs) {
		Map<String, String> nameValMap = getNameVal(simpleUseArgs);
		return replaceByMap(code, nameValMap);
	}
	
	private static Map<String,String> getNameVal(List<SimpleUseArgConf> simpleUseArgs){
		Map<String,String> result = Maps.newHashMap();
		for(SimpleUseArgConf conf : simpleUseArgs){
			result.put(conf.getName(), conf.getVal());
		}
		
		return result;
	}
}
